import { DoublyLinkedList } from '..';
import { IEqualsFunction, defaultEquals } from '../util';
/**
 * 在双向链表的基础上，将尾部元素的next指向首部元素，将首
 * 部元素的prev指向尾部元素，以此形成循环。
 * 需要重写push、unshift、removeAt、clear等方法
 */
export default class DoublyCircularLinkedList<T> extends DoublyLinkedList<T> {
    constructor(equalsFn: IEqualsFunction<T> = defaultEquals) {
        super(equalsFn);
    }
    /**
     * 向链表尾部添加元素（重写）
     */
    public push(element: T) {
        super.push(element);
        this.formingCycle();
    }
    /**
     * 向链表首部添加元素（重写）
     */
    public unshift(element: T) {
        super.unshift(element);
        this.formingCycle();
    }
    /**
     * 从链表中移除指定位置的元素（重写）
     */
    public removeAt(index: number): T {
        const result: T = super.removeAt(index);
        // 特殊情况操作第一个或最后一个位置，操作其他位置都是不影响循环的，可查看super.removeAt逻辑
        if (result != null && (index === 0 || index === this.count)) {
            this.formingCycle();
        }
        return result;
    }
    /**
     * 构成新循环：尾部的next指向this.heads，首部的prev指向this.tail
     */
    private formingCycle() {
        if (!this.isEmpty()) {
            this.tail.next = this.head; // 构成双向循环
            this.head.prev = this.tail;
        }
    }
    /**
     * 清空（考虑到可能有循环引用的问题）
     */
    public clear() {
        if (this.tail != null) {
            this.tail.next = undefined;
        }
        if (this.head != null) {
            this.head.prev = undefined;
        }
        super.clear();
    }
}
